<?php
// 应用公共文件
use app\api\controller\Wxsdk;
use think\facade\View;
use think\facade\Db;
use think\facade\Config;
use app\admin\model\Log;
use think\facade\Cache;

/**
 * 封装post请求
 */
function curl_post($url,$data){
    $header = array('Content-Type: application/json; charset=utf-8');
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_TIMEOUT, 10);
    $output = curl_exec($ch);
    curl_close($ch);
    return $output;
}
/**
 * 封装请求
 */
function httpRequest($url, $data = null,$header=null) {
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
    if (!empty($data)) {
        curl_setopt($curl, CURLOPT_POST, 1);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }
    if($header) {
        curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
    }
    curl_setopt($curl, CURLOPT_HEADER, 0);//返回response头部信息
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    //执行
    $output = curl_exec($curl);
    curl_close($curl);
    return $output;
}
/**
 * 后台权限验证
 */
function adminAuthCheck($route,$routeArr){
    return in_array($route,$routeArr)?"":"ts-hide";
}


/**
 * 请求成功时返回
 */
function successReturn($msg="",$data=[],$code="200"){
    $successArr=[
        "code"=>$code,
        "data"=>$data,
        "msg"=>$msg,
    ];
    exit(json_encode($successArr,JSON_UNESCAPED_UNICODE));
}

/**
 * 请求失败时返回
 */
function errorReturn($msg="",$data=[],$code="400"){
    $errArr=[
        "code"=>$code,
        "data"=>$data,
        "msg"=>$msg,
    ];
    exit(json_encode($errArr,JSON_UNESCAPED_UNICODE));
}

/**
 * 查询所有数据，返回数组格式
 */
function getDbAll($tableName,$where=[],$order="",$group="",$field=""){
    $query=Db::name($tableName);
    if($where) $query->where($where);
    if($order) $query->order($order);
    if($group) $query->group($group);
    if($field) $query->field($field);
    return $query->select()->toArray();
}

/**
 * 查询单条数据，返回数组格式
 */
function getDbOne($tableName,$where=[],$order="",$group="",$field=""){
    $query=Db::name($tableName);
    if($where) $query->where($where);
    if($order) $query->order($order);
    if($group) $query->group($group);
    if($field) $query->field($field);
    return $query->find()->toArray();
}

/**
 * 根据ID获取返回的名字
 * $tablename 表名 $id查询条件的id  $filed 返回的字段名
 * type=0 返回字符串 type=1 返回数组
 */
function getName($tablename,$id,$filed,$type=0){
    $query=Db::name($tablename)->where("id in ($id)");
    if($filed) $query= $query->field($filed);
    $results=$query->select()->toArray();
    if($results) return implode(",",array_column($results, $filed));
    return "";
}
/**
 * 模板赋值
 * @param string $name
 * @param data $value
 * @return void
 */
function assign($name, $value)
{
    View::assign($name, $value);
}

/**
 * @return mixed
 * 返回配置文件信息
 */
function getConfig($fileName){
    return Config::get($fileName);
}


/**
 * 获取日志名称信息
 * @param $number
 * @return int|string|void
 */
function getMenuName($name){
    $msg = Config::get('admin_log.'.$name.'');

    if(empty($msg) || $msg == '' || !$msg)
    {
        return '';
    }
    return $msg;
}

/**
 * 获取缓存
 * @param string $key 缓存名字
 */
function getCache($key){
    Cache::get($key);
}
/**
 * 写入缓存
 * @param string $key 缓存名字
 * @param value $value 缓存内容
 * @return int $ttl 时间
 */
function setCache($key,$value,$ttl = 0){
    if(empty($ttl)){
        Cache::set($key,$value);
    }else{
        Cache::set($key,$value,$ttl);
    }
}

/**
 * 获取客户端IP地址
 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
 * @param boolean $adv 是否进行高级模式获取（有可能被伪装）
 * @return mixed
 */
function getRealIP($type = 0,$adv=false)
{
    $type = $type ? 1 : 0;
    static $ip = NULL;
    if($ip !== NULL) return $ip[$type];
    if($adv) {
        if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
            $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
            $pos = array_search('unknown',$arr);
            if(false !== $pos) unset($arr[$pos]);
            $ip = trim($arr[0]);
        } elseif(isset($_SERVER['HTTP_CLIENT_IP'])) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif(isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
    } elseif(isset($_SERVER['REMOTE_ADDR'])) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = sprintf("%u",ip2long($ip));
    $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
    return $ip[$type];
}

/**
 * 记录系统日志
 * @param string $username
 * @param int $type
 * @param text $operation
 * @return void
 */
function setLog($username, $type, $operation)
{
    $data = [
        'username' => $username,
        'type' => $type,
        'action' => $operation,
        'ip' => getRealIP(),
        'createdate' => time(),
    ];

    $log = new Log();
    $log->insData($data);
}



/**
 * 判断当前项目的域名和http协议
 * @return string
 */
function getUrl()
{
    $http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://';
    return $http_type . $_SERVER['HTTP_HOST'] . '/';
}


/**
 * 图片上传，支持单张和多图
 * @return array
 */
function imageUpload($type = '',$obj='image')
{
    if($type == 'more')
    {
        // 获取表单上传文件
        $files = request()->file($obj);
        // 获取表单上传文件 例如上传了001.jpg
        $savename = [];
        // 上传到本地服务器
        foreach($files as $file)
        {
            $savename[] = \think\facade\Filesystem::putFile( 'upload', $file);
        }
    } else {
        // 获取表单上传文件 例如上传了001.jpg
        $file = request()->file($obj);
        // 上传到本地服务器
        $savename = \think\facade\Filesystem::putFile( 'upload', $file);
    }
    return $savename;
}

/**
 * 图片上传，支持单张和多图
 * @return array
 */
function posterUpload()
{
    // 获取表单上传文件 例如上传了001.jpg
    $file = request()->file('image');
    // 上传到本地服务器
    $savename = \think\facade\Filesystem::putFile( 'upload/poster', $file);
    return $savename;
}


/**
 * 给图片加边框
 * @param $ImgUrl	图片地址
 * @param $SavePath	新图片保存路径
 * @param $px	边框像素（2表示左右各一像素）
 * @return Ambigous <boolean, 新图片的路径>
 */
function ImageAddBoard($ImgUrl, $SavePath, $px = 2) {
    $aPathInfo = pathinfo ( $ImgUrl );
    // 文件名称
    $sFileName = $aPathInfo ['filename'];
    // 图片扩展名
    $sExtension = $aPathInfo ['extension'];
    // 获取原图大小
    $size = getimagesize($ImgUrl);
    $img_w = $size[0];
    $img_h = $size[1];
    // 读取图片
    if (strtolower ( $sExtension ) == 'png') {
        $resource = imagecreatefromstring(file_get_contents(($ImgUrl)));
    } elseif (strtolower ( $sExtension ) == 'jpg' || strtolower ( $sExtension ) == 'jpeg') {
        $resource = imagecreatefromjpeg ( $ImgUrl );
    }
    // 282*282的黑色背景图片
    $im = @imagecreatetruecolor ( ($img_w + $px), ($img_h + $px) ) or die ( "Cannot Initialize new GD image stream" );
    // 为真彩色画布创建背景，再设置为透明
    $color = imagecolorallocate ( $im, 0, 0, 0 );
    // 把品牌LOGO图片放到黑色背景图片上。边框是1px
    imagecopy ( $im, $resource, $px / 2, $px / 2, 0, 0, $size[0], $size[1] );

    $imgNewUrl = $SavePath . $sFileName . '-n.' . $sExtension;
    if (strtolower ( $sExtension ) == 'png') {
        $ret = imagepng ( $im, $imgNewUrl );
    } elseif (strtolower ( $sExtension ) == 'jpg' || strtolower ( $sExtension ) == 'jpeg') {
        $ret = imagejpeg ( $im, $imgNewUrl );
    }
    imagedestroy ( $im );
    return $ret ? $imgNewUrl : false;
}

/**
 * 生成宣传海报
 * @param array  参数,包括图片和文字
 * @param string  $filename 生成海报文件名,不传此参数则不生成文件,直接输出图片
 * @return [type] [description]
 */
function createPoster($config = array() , $filename = "")
{
    //如果要看报什么错，可以先注释调这个header
    if (empty($filename)) header("content-type: image/png");
    $imageDefault = array(
        'left' => 0,
        'top' => 0,
        'right' => 0,
        'bottom' => 0,
        'width' => 100,
        'height' => 100,
        'opacity' => 100
    );
    $textDefault = array(
        'text' => '默认文字',
        'left' => 0,
        'top' => 0,
        'fontSize' => 32, //字号
        'fontColor' => '255,255,255', //字体颜色
        'angle' => 0,
    );
    $background = $config['background']; //海报最底层得背景
    //背景方法
    $backgroundInfo = getimagesize($background);
    $backgroundFun = 'imagecreatefrom' . image_type_to_extension($backgroundInfo[2], false);
    $background = $backgroundFun($background);
    $backgroundWidth = imagesx($background); //背景宽度
    $backgroundHeight = imagesy($background); //背景高度
    $imageRes = imageCreatetruecolor($backgroundWidth, $backgroundHeight);
    $color = imagecolorallocate($imageRes, 0, 0, 0);
    imagefill($imageRes, 0, 0, $color);
    imagecopyresampled($imageRes, $background, 0, 0, 0, 0, imagesx($background) , imagesy($background) , imagesx($background) , imagesy($background));
    //处理了图片
    if (!empty($config['image']))
    {
        foreach ($config['image'] as $key => $val)
        {
            $val = array_merge($imageDefault, $val);
            $info = getimagesize($val['url']);
            $function = 'imagecreatefrom' . image_type_to_extension($info[2], false);
            if ($val['stream'])
            {
                //如果传的是字符串图像流
                $info = getimagesizefromstring($val['url']);
                $function = 'imagecreatefromstring';
            }
            $res = $function($val['url']);
            $resWidth = $info[0];
            $resHeight = $info[1];
            //建立画板 ，缩放图片至指定尺寸
            $canvas = imagecreatetruecolor($val['width'], $val['height']);
            imagefill($canvas, 0, 0, $color);
            //如果是透明的gif或png做透明处理
            $ext = pathinfo($val['url']);
            if (array_key_exists('extension',$ext))
            {
                if ($ext['extension'] == 'gif' || $ext['extension'] == 'png')
                {
                    imageColorTransparent($canvas, $color); //颜色透明
                }
            }
            //关键函数，参数（目标资源，源，目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h）
            imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'], $resWidth, $resHeight);
            //$val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']) - $val['width']:$val['left'];
            //如果left小于-1我这做成了计算让其水平居中
            if ($val['left'] < 0)
            {
                $val['left'] = ceil($backgroundWidth - $val['width']) / 2;
            }
            //$val['top'] = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) - $val['height'] : $val['top'];
            //放置图像
            imagecopymerge($imageRes, $canvas, $val['left'], $val['top'], $val['right'], $val['bottom'], $val['width'], $val['height'], $val['opacity']); //左，上，右，下，宽度，高度，透明度
            if($val['type'] == 'code'){//是二维码图片 加边框
                imagecopymerge($imageRes, $canvas, $val['left'], $val['top'], $val['right'], $val['bottom'], $val['width'], $val['height'], $val['opacity']);
            }
        }
    }

    //处理文字
    if (!empty($config['text']))
    {
        foreach ($config['text'] as $key => $val)
        {
            $val = array_merge($textDefault, $val);
            list($R, $G, $B) = explode(',', $val['fontColor']);
            $fontColor = imagecolorallocate($imageRes, $R, $G, $B);
            //$val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']):$val['left'];
            //如果left小于-1我这做成了计算让其水平居中
            $fontBox = imagettfbbox($val['fontSize'], 0, $val['fontPath'], $val['text']); //文字水平居中实质
            if ($val['left'] < 0)
            {
                $val['left'] = ceil($val['left'] - ($fontBox[2] - $fontBox[0]) / 2); //计算用户昵称相对头像的相对居中坐标
                //$val['left'] = ceil(($backgroundWidth - $fontBox[2]) / 2); //计算文字的水平位置
            }
            else
            {
                //计算用户昵称相对头像的相对居中坐标 - 昵称长度大于头像宽度时
                if(($fontBox[2] - $fontBox[0]) > 200)
                {
                    $val['left'] = $val['left'] - (($fontBox[2] - $fontBox[0]) - 200) / 2 ;
                }
                //计算用户昵称相对头像的相对居中坐标 - 昵称长度小于头像宽度时
                else
                {
                    $val['left'] = ceil((200 - ($fontBox[2] - $fontBox[0])) / 2) + $val['left'];
                }
            }
            //$val['top'] = $val['top'] < 0 ? $backgroundHeight - abs($val['top']) : $val['top'];
            imagettftext($imageRes, $val['fontSize'], $val['angle'], $val['left'], $val['top'], $fontColor, $val['fontPath'], $val['text']);
        }
    }
    //生成图片
    if (!empty($filename))
    {
        $res = imagejpeg($imageRes, $filename, 90); //保存到本地
        imagedestroy($imageRes);
        if (!$res) return false;

        return $filename;
    } else
    {
        header("Content-type:image/png");
        imagejpeg($imageRes); //在浏览器上显示
        imagedestroy($imageRes);
    }
}

/**
 * 数组从新排序
 * @param array 数组对象
 * @param keys  根据数组某个字段排序
 * @return sort 排序方式
 */
function arraySort($array,$keys,$sort='asc'){
    $newArr = $valArr = array();
    foreach ($array as $key=>$value) {
        $valArr[$key] = $value[$keys];
    }
    ($sort == 'asc') ? asort($valArr) : arsort($valArr);//先利用keys对数组排序，目的是把目标数组的key排好序
    reset($valArr); //指针指向数组第一个值
    foreach($valArr as $key=>$value) {
        $newArr[$key] = $array[$key];
    }
    return $newArr;
}

/**
 * 生成二维码
 * @param $img
 * @param $logo
 * @return mixed
 */
function createQrcode($img, $logo)
{
    $code = new \dh2y\qrcode\QRcode();
    $res = $code->png($img)->logo($logo)->entry();

    return $res;
}

/**
 * 快递100请求CURL
 * @param $url
 * @param $post_data
 * @return mixed
 */
function express_curl($url, $post_data)
{
    //发送post请求
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    $result = curl_exec($ch);
    $data = json_decode($result, true);
    return $data;
}


/**
 * 计算指定时间段内的天数
 * @param $sTime
 * @param $eTime
 * @return float
 */
function getCountDays($sTime, $eTime)
{
    $startDt = getdate($sTime);
    $endDt = getdate($eTime);
    $sUTime = mktime(12, 0, 0, $startDt['mon'], $startDt['mday'], $startDt['year']);
    $eUTime = mktime(12, 0, 0, $endDt['mon'], $endDt['mday'], $endDt['year']);

    return round(abs($sUTime - $eUTime) / 86400);
}


//将表情进行转义  用于存储的时候
function emoji_encode($str){
    $strEncode = '';
    $length = mb_strlen($str,'utf-8');
    for ($i=0; $i < $length; $i++) {
        $_tmpStr = mb_substr($str,$i,1,'utf-8');
        if(strlen($_tmpStr) >= 4){
            $strEncode .= '[[EMOJI:'.rawurlencode($_tmpStr).']]';
        }else{
            $strEncode .= $_tmpStr;
        }
    }
    return $strEncode;
}

//将表情进行反转义  用于读取的时候
function emoji_decode($str){
    $strDecode = preg_replace_callback('|\[\[EMOJI:(.*?)\]\]|', function($matches){
        return rawurldecode($matches[1]);
    }, $str);
    return $strDecode;
}



/**
 * Excel导入
 * @param string $filename 文档地址
 * @param array $name 要获取的字段名称
 * @return false|string
 */
function excelImport($filename,$name){
    require_once root_path().'/vendor/PHPExcel/PHPExcel/IOFactory.php';
    //加载excel文件
    $objPHPExcelReader = PHPExcel_IOFactory::load($filename);
    $sheet = $objPHPExcelReader->getSheet(0);        // 读取第一个工作表(编号从 0 开始)
    $highestRow = $sheet->getHighestRow();           // 取得总行数
    $highestColumn = $sheet->getHighestColumn();     // 取得总列数
    $arr = array('A','B','C','D','E','F','G','H','I','J','K','L','M', 'N','O','P','Q','R','S','T','U','V','W','X','Y','Z');
    // 一次读取一列
    if(!empty($name)){
        $row_arr_name = array();
        for ($column = 0; $arr[$column] != 'Z'; $column++) {
            $val = $sheet->getCellByColumnAndRow($column, 1)->getValue();
            if(in_array($val,$name)){
                $row_arr_name[$column] = $val;
            }
        }
    }
    $res_arr = array();
    for ($row = 2; $row <= $highestRow; $row++) {
        $row_arr = array();
        if(!empty($row_arr_name)){//有字段根据字段获取，没有的话就获取全部
            foreach($row_arr_name as $k=>$v){
                $val = $sheet->getCellByColumnAndRow($k, $row)->getValue();
                $row_arr[] = $val;
            }
        }else{
            for ($column = 0; $arr[$column] != 'Z'; $column++) {
                $val = $sheet->getCellByColumnAndRow($column, $row)->getValue();
                $row_arr[] = $val;
            }
        }
        $res_arr[] = $row_arr;
    }
    return $res_arr;
}

/**
 * PHPExcel 导出
 * @param array $tltie EXCEL内容标题栏
 * @param array $value EXCEL内容
 * @param string $name EXCEL文件标题
 */
function excelDownload($tltie,$value,$name)
{
    require_once root_path().'/vendor/PHPExcel/PHPExcel.php';
    //实例化phpexcel对象
    // Create new PHPExcel object
    $objPHPExcel = new \PHPExcel();
    // Set document properties
    $objPHPExcel->getProperties()->setCreator("Maarten Balliauw")
        ->setLastModifiedBy("Maarten Balliauw")
        ->setTitle("Office 2007 XLSX Test Document")
        ->setSubject("Office 2007 XLSX Test Document")
        ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
        ->setKeywords("office 2007 openxml php")
        ->setCategory("Test result file");
    $letter = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
    // Add some data
    foreach ($tltie as $k=>$v){
        $objPHPExcel->setActiveSheetIndex(0)->setCellValue($letter[$k].'1', $v);
    }
    foreach ($value as $k=>$v){
        foreach($v as $vk=>$vv){
            $num = $k+2;
            $numkey = $letter[$vk].$num;
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue($numkey, $vv);
        }
    }
    // Rename worksheet
    $objPHPExcel->getActiveSheet()->setTitle('Simple');
    // Set active sheet index to the first sheet, so Excel opens this as the first sheet
    $objPHPExcel->setActiveSheetIndex(0);
    // Redirect output to a client’s web browser (Excel2007)
    header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    header('Content-Disposition: attachment;filename="'.$name.'.xlsx"');
    header('Cache-Control: max-age=0');
    // If you're serving to IE 9, then the following may be needed
    header('Cache-Control: max-age=1');

    header ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
    header ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified
    header ('Cache-Control: cache, must-revalidate'); // HTTP/1.1
    header ('Pragma: public'); // HTTP/1.0

    $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
    $objWriter->save('php://output');
}
